package com.therandoms.rtgdroid.steps;

import java.util.ArrayList;

import org.codepond.wizardroid.WizardStep;
import org.codepond.wizardroid.persistence.ContextVariable;
import org.therandoms.textgen.TextGeneratorDictionary;

import com.therandoms.rtgdroid.R;
import com.therandoms.rtgdroid.background.GrammarFileLoadTask;
import com.therandoms.rtgdroid.util.SecondarySubstitutionMode;

import com.nononsenseapps.filepicker.FilePickerActivity;

import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public class SecondarySubstitutionSettingsStep extends WizardStep {

	private static final int FILE_REQUEST_CODE = 1;

	@Override
	public void onExit(int exitCode) {
		if (exitCode == EXIT_NEXT) {
			// form the word lists if substitution desired.
			if (secondarySubstitutionMode
					.equals(SecondarySubstitutionMode.N_CHARS)
					|| secondarySubstitutionMode
							.equals(SecondarySubstitutionMode.N_CHARS_TRUNCATE)
					|| secondarySubstitutionMode
							.equals(SecondarySubstitutionMode.WORD_LEVEL)) {
				StringBuilder sb = new StringBuilder();
				for (String s : outList) {
					// truncate: simply add the words trimmed to at most n chars
					if (secondarySubstitutionMode
							.equals(SecondarySubstitutionMode.N_CHARS_TRUNCATE)) {
						secondarySubstituteList.add(s.substring(0,
								Math.min(secondaryWordSize, s.length())));
					}
					else if(secondarySubstitutionMode.equals(SecondarySubstitutionMode.WORD_LEVEL)){
						secondarySubstituteList.add(s);
					}

					// otherwise, make a huge buffer.
					else {
						sb.append(s);
					}
				}

				// if buffer option used, split the buffer into chunks of length
				// n.
				if (secondarySubstitutionMode
						.equals(SecondarySubstitutionMode.N_CHARS)) {
					System.out.println("Buffer: " + sb);
					for (int i = 0; i < sb.length(); i += secondaryWordSize) {
						secondarySubstituteList.add(sb.substring(i,
								Math.min(i + secondaryWordSize, sb.length())));
					}
				}
			}
			
		}
		
		super.onExit(exitCode);
	}

	/**
	 * Stores the result of the random generation.
	 */
	@ContextVariable
	private ArrayList<String> outList;

	/**
	 * Stores the words to pass to the secondary substitution grammar.
	 */
	@ContextVariable
	private ArrayList<String> secondarySubstituteList;

	/**
	 * The spinner to use to select a secondary option.
	 */
	private Spinner secondaryOptionSpinner;

	/**
	 * The textbox for the size of each secondary word.
	 */
	private EditText numberInput;

	/**
	 * The label for numberInput
	 */
	private TextView numberInputPrompt;

	/**
	 * The label for fileInputButton
	 */
	private TextView fileInputPrompt;

	/**
	 * The button used to select the file.
	 */
	private Button fileInputButton;

	/**
	 * Stores the secondary word size.
	 */
	private int secondaryWordSize = -1;

	/**
	 * Stores the secondary substitution mode.
	 */
	private SecondarySubstitutionMode secondarySubstitutionMode = SecondarySubstitutionMode.NONE;

	/**
	 * The dictionary for secondary substitution.
	 */
	@ContextVariable
	private TextGeneratorDictionary<String> secondarySubstitutionDictionary = new TextGeneratorDictionary<String>();

	private TextWatcher mWatcher = new TextWatcher() {

		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			// TODO Auto-generated method stub

		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after) {
			// TODO Auto-generated method stub

		}

		@Override
		public void afterTextChanged(Editable s) {
			String numStr = s.toString();
			try {
				secondaryWordSize = -1;
				Float mFloat = Float.parseFloat(numStr);
				if(mFloat.isNaN() || mFloat.isInfinite()){
					mFloat = (float) -1;
				}
				secondaryWordSize = mFloat.intValue();
				System.out.println("Secondary word size " + secondaryWordSize);
				
				// this works because numberInput is shown only for the
				// ngram modes, which require number and grammar.
				if (secondaryWordSize > 0
						&& secondarySubstitutionDictionary
								.getProductionCategories().size() > 0) {
					notifyCompleted(true);
					System.out.println("NotifyTrue 4");
				} else {
					System.out.println("NotifyFalse 3");
					notifyCompleted(false);
				}
			} catch (Exception e) {
				secondaryWordSize = -1;
				System.out.println("NotifyFalse 4");
				notifyCompleted(false);
			}
		}
	};

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.step_secondary_substitution_mode,
				container, false);

		//precondition: need text to transform
		if (outList.size() <= 0) {
			return v;
		}
		
		fileInputButton = (Button) v
				.findViewById(R.id.secondary_grammar_file_select);
		fileInputPrompt = (TextView) v
				.findViewById(R.id.secondary_grammar_file_prompt);

		numberInput = (EditText) v
				.findViewById(R.id.secondary_substitution_ngram_edit);
		numberInputPrompt = (TextView) v
				.findViewById(R.id.secondary_substitution_ngram_prompt);

		secondaryOptionSpinner = (Spinner) v
				.findViewById(R.id.substitution_options_spinner);

		// the file input button starts the file chooser.
		fileInputButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent fileChooserIntent = new Intent(getActivity(),
						FilePickerActivity.class);
				fileChooserIntent.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false);
				fileChooserIntent.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false);
				fileChooserIntent.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE);
				
				startActivityForResult(fileChooserIntent, FILE_REQUEST_CODE);
			}
		});

		secondaryOptionSpinner
				.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View view,
							int position, long id) {
						secondarySubstitutionMode = SecondarySubstitutionMode
								.values()[position];
						// No substitution desired; hide everything and say we
						// are ready
						if (secondarySubstitutionMode
								.equals(SecondarySubstitutionMode.NONE)) {
							numberInput.setVisibility(View.GONE);
							numberInputPrompt.setVisibility(View.GONE);
							numberInput.removeTextChangedListener(mWatcher);

							fileInputButton.setVisibility(View.GONE);
							fileInputPrompt.setVisibility(View.GONE);

							System.out.println("NotifyTrue 1");
							notifyCompleted(true);
						}

						// Word level substitution desired; prompt for grammar.
						else if (secondarySubstitutionMode
								.equals(SecondarySubstitutionMode.WORD_LEVEL)) {
							numberInput.setVisibility(View.GONE);
							numberInputPrompt.setVisibility(View.GONE);
							numberInput.removeTextChangedListener(mWatcher);
							numberInput.getText().clear();
							secondaryWordSize = -1;
							
							fileInputButton.setVisibility(View.VISIBLE);
							fileInputPrompt.setVisibility(View.VISIBLE);

							System.out.println("NotifyFalse wordlevel");
							notifyCompleted(false);
						}

						// N-gram substitution desired; prompt for grammar and
						// value of n.
						else if (secondarySubstitutionMode
								.equals(SecondarySubstitutionMode.N_CHARS)
								|| secondarySubstitutionMode
										.equals(SecondarySubstitutionMode.N_CHARS_TRUNCATE)) {
							numberInput.setVisibility(View.VISIBLE);
							numberInputPrompt.setVisibility(View.VISIBLE);
							numberInput.addTextChangedListener(mWatcher);
							numberInput.getText().clear();
							secondaryWordSize = -1;

							fileInputButton.setVisibility(View.VISIBLE);
							fileInputPrompt.setVisibility(View.VISIBLE);

							System.out.println("NotifyFalse ngram");
							notifyCompleted(false);
						}
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
						// TODO Auto-generated method stub

					}
				});
		return v;
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		// Call super
		super.onActivityResult(requestCode, resultCode, data);

		// File has been chosen. Try to load from it.
		if (requestCode == FILE_REQUEST_CODE
				&& resultCode == FilePickerActivity.RESULT_OK) {
			Crouton.cancelAllCroutons();
			GrammarFileLoadTask mTask = new GrammarFileLoadTask() {

				@Override
				protected void onPostExecute(
						TextGeneratorDictionary<String> result) {
					secondarySubstitutionDictionary = result;
					// if this is true then loading succeeded.
					if (result.getProductionCategories().size() > 0) {
						// we are in an n-gram mode. Check that word size is
						// valid.
						if (secondarySubstitutionMode
								.equals(SecondarySubstitutionMode.N_CHARS)
								|| secondarySubstitutionMode
										.equals(SecondarySubstitutionMode.N_CHARS_TRUNCATE)) {
							if (secondaryWordSize > 0) {
								System.out.println("NotifyTrue 5");
								notifyCompleted(true);
							} else {
								System.out.println("NotifyFalse 5");
								notifyCompleted(false);
							}
						} else {
							System.out.println("NotifyTrue 6");
							notifyCompleted(true);
						}
					}

					// if this is true then loading failed.
					else {
						Crouton.makeText(getActivity(),
								R.string.select_grammar_file_alert, Style.ALERT);
						System.out.println("NotifyFalse 6");
						notifyCompleted(false);
					}
				}

			};
			System.out.println(data.getData().getPath());
			mTask.execute(data.getData().getPath());
		}
	}
}
